﻿/*
 * Created by SharpDevelop.
 * User: netcasewqs@gmail.com
 * Date: 2010-9-20
 * Time: 18:08
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */
using System;
using System.Collections.Generic;
using System.Linq;

namespace NLite.Data
{
	/// <summary>
	/// 
	/// </summary>
	public interface IPagination<T>:IEnumerable<T>
	{
		/// <summary>
		/// 
		/// </summary>
		uint TotalRowCount{get;}
		/// <summary>
		/// 
		/// </summary>
		uint PageSize { get;}
		/// <summary>
		/// 
		/// </summary>
		uint StartRowIndex { get;}
		/// <summary>
		/// 
		/// </summary>
		uint PageNumber { get;}
		/// <summary>
		/// 
		/// </summary>
		uint Length { get ;}
		/// <summary>
		/// 
		/// </summary>
		uint PageCount{get;}
	}
	namespace Internal
	{
		/// <summary>
		/// 
		/// </summary>
		internal class Pagination<T> : IPagination<T>
		{
			private readonly IEnumerable<T> _collection;
			
			/// <summary>
			/// 
			/// </summary>
			public uint TotalRowCount { get; private set; }
			/// <summary>
			/// 
			/// </summary>
			public uint PageSize { get; private set; }
			/// <summary>
			/// 
			/// </summary>
			public uint StartRowIndex { get; private set; }
			/// <summary>
			/// 
			/// </summary>
			public uint PageNumber { get { return (StartRowIndex / PageSize); } }
			
			/// <summary>
			/// 
			/// </summary>
			public uint Length { get { return (uint)_collection.Count(); } }
			/// <summary>
			/// 
			/// </summary>
			public uint PageCount
			{
				get { return (uint)Math.Ceiling((double)TotalRowCount / (double)PageSize); }
			}

			/// <summary>
			/// 
			/// </summary>
			/// <param name="collection"></param>
			/// <param name="startIndex"></param>
			/// <param name="pageSize"></param>
			/// <param name="totalCount"></param>
			public Pagination(IEnumerable<T> collection, uint startIndex, uint pageSize, uint totalCount)
			{
				if (collection == null)
					_collection = Enumerable.Empty<T>();
				else
					_collection = collection;
				StartRowIndex = startIndex;
				PageSize = pageSize;
				TotalRowCount = totalCount;

				if (Length > PageSize)
					_collection = _collection.Skip((int)StartRowIndex).Take((int)PageSize);
			}

			#region IEnumerable<T> Members

			/// <summary>
			/// 
			/// </summary>
			/// <returns></returns>
			public IEnumerator<T> GetEnumerator()
			{
				return _collection.GetEnumerator();
			}

			#endregion

			#region IEnumerable Members

			System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
			{
				return _collection.GetEnumerator();
			}

			#endregion

			/// <summary>
			/// 
			/// </summary>
			public static Pagination<T> Empty
			{
				get
				{
					return new Pagination<T>(Enumerable.Empty<T>(), 0, 10, 0);
				}
			}

			
		}
	}
}
